#include <algorithm>
#include <string.h>

#ifndef PURG_C_INTERFACE_COMPILE
namespace  purg
{
#endif

  buffer::buffer ( size_t  len )
    : _length ( len )
  {
    _buffer = static_cast<void *> ( new unsigned char [ len ] );
  }

  buffer::~buffer ()
  {
    delete [] static_cast<unsigned char *> ( _buffer );
  }

  buffer::operator unsigned char * ()
  {
    return static_cast<unsigned char *> (_buffer);
  }

  size_t buffer::size()
  {
    return _length;
  }

  void buffer::resize ( size_t i )
  {
    unsigned char *t = static_cast<unsigned char *> (_buffer);
    _buffer = static_cast<void *> ( new unsigned char [ i ] );
    memcpy ( _buffer , t , std::min ( _length , i ) );
    _length = i;
    delete [] static_cast<unsigned char *> ( t );
  }

  unsigned char &buffer::operator [] ( size_t i )
  {
    return static_cast<unsigned char *> (_buffer )[i];
  }

  size_t  buffer::copyTo ( void *destination , size_t offset , size_t start , size_t amount , size_t max_len )
  {
    size_t  length;
    if ( max_len == 0 )
      length = std::min ( amount , _length - start );
    else
      length = std::min ( amount , max_len - start );
    unsigned char *buf = static_cast<unsigned char *>(_buffer) + start;
    unsigned char *dest = static_cast<unsigned char *>(destination) + offset;
    memcpy ( dest , buf , length );
    return length;
  }

  size_t  buffer::xorTo ( void *destination , size_t offset , size_t start , size_t amount , size_t max_len )
  {
    size_t  length;
    if ( max_len == 0 )
      length = std::min ( amount , _length - start );
    else
      length = std::min ( amount , max_len - start );
    unsigned char *dest = static_cast<unsigned char *> ( destination ) + offset;
    unsigned char *buf = static_cast<unsigned char *>(_buffer) + start;
    for ( size_t i = 0 ; i != length ; i++ )
    {
      *(dest++) ^= *(buf++);
    }
    return length;
  }
#ifndef PURG_C_INTERFACE_COMPILE
}
#endif

